/*
DATE: 2021/12/13
AUTHOR: chenyihui
Desc:  基于github.com/gomodule/redigo/redis 实现的分布式锁

*/
package redigo

import (
	"gitee.com/e1va/redislock"
	"github.com/gomodule/redigo/redis"
	"strings"
	"time"
)

type pool struct {
	// TODO  待优化。
	//c cache.Cache

	redSync redislock.RedSyncPool
}

func NewPool() redislock.RedSyncPool {
	return &pool{}
}

func (p *pool) Get() redislock.Conn {
	return &conn{}
}

type conn struct {
	c redis.Conn
}

func (c *conn) SetNx(key string, value interface{}, expireAt time.Duration) (bool, error) {
	reply, err := redis.String(c.c.Do("SET", key, value, "NX", "PX", int(expireAt/time.Millisecond)))
	return reply == "OK", redislock.NoErrNil(err)
}

func (c *conn) Eval(script *redislock.Script, keysAndArgs ...interface{}) (interface{}, error) {
	v, err := c.c.Do("EVALSHA", redislock.Args(script, script.Hash, keysAndArgs)...)
	if e, ok := err.(redis.Error); ok && strings.HasPrefix(string(e), "NOSCRIPT ") {
		v, err = c.c.Do("EVAL", redislock.Args(script, script.Src, keysAndArgs)...)
	}
	return v, redislock.NoErrNil(err)
}

func (c *conn) Close() error {
	return c.c.Close()
}
